package cn.udrm.water.base.v1.manager.service;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.udrm.water.base.v1.manager.cache.BasePersonCache;
import cn.udrm.water.base.v1.manager.dto.BasePersonDto;
import cn.udrm.water.base.v1.manager.dto.BasePersonDtoMapper;
import cn.udrm.water.base.v1.manager.dto.BaseRoleDto;
import cn.udrm.water.base.v1.manager.dto.BaseRoleDtoMapper;
import cn.udrm.water.base.v1.manager.entities.BaseDepartment;
import cn.udrm.water.base.v1.manager.entities.BasePerson;
import cn.udrm.water.base.v1.manager.entities.BaseRole;
import cn.udrm.water.base.v1.manager.repository.BaseDepartmentRepository;
import cn.udrm.water.base.v1.manager.repository.BasePersonRepository;

@Service
@Transactional(readOnly=true)
@CacheConfig(cacheNames="base_persons")
public class BasePersonService {
	@Autowired
	private BasePersonCache personCache;
	@Autowired
	private BasePersonRepository personRepository;
	@Autowired
	private BasePersonDtoMapper personDtoMapper;
	@Autowired
	private BaseDepartmentRepository baseDepartmentRepository;
	@Autowired
	private BaseRoleDtoMapper roleDtoMapper;
	
	@Cacheable(key="methodName+#p0")
	public BasePersonDto getWithRoles(String id) {
		BasePerson findWithRolesById = personRepository.findWithRolesById(id);
		if (findWithRolesById != null) {
			List<BaseRole> roles = findWithRolesById.getRoles();
			BasePersonDto from = personDtoMapper.from(findWithRolesById);
			if (roles != null) {
				List<BaseRoleDto> roleDtos = roleDtoMapper.from(roles);
				from.setRoleDtos(roleDtos);
			}
			return from;
		}
		return null;
	}
	
	@Cacheable(key="methodName+#p0")
	public BasePersonDto getSelfById(String id) {
		BasePerson selfById = personRepository.getSelfById(id);
		if (selfById != null) {
			BasePersonDto from = personDtoMapper.from(selfById);
			return from;
		}
		return null;
	}
	
	@Transactional(readOnly=false)
	public BasePersonDto save(BasePersonDto personDto) {
		if (personDto != null) {
			BasePerson basePerson = personDtoMapper.to(personDto);
			basePerson.setId(null);
			BaseDepartment dept = null;
			String departmentGuid = personDto.getDepartmentGuid();
			if (StringUtils.isNotBlank(departmentGuid)) {
				dept = baseDepartmentRepository.findSelfById(departmentGuid);
			}
			if (dept != null && StringUtils.isNotBlank(dept.getId())) {
				basePerson.setDepartment(dept);
			}
			/*
			 * 设置所属角色
			 */
			List<BaseRole> roles = null;
			List<BaseRoleDto> roleDtos = personDto.getRoleDtos();
			if (roleDtos != null && roleDtos.size() != 0) {
				roles = new ArrayList<BaseRole>();
				for (BaseRoleDto baseRoleDto : roleDtos) {
					roles.add(new BaseRole(baseRoleDto.getId()));
				}
			}
			if (roles != null) {
				basePerson.setRoles(roles);
			}
			basePerson = personCache.saveAndFlush(basePerson);
			return personDtoMapper.from(basePerson);
		}
		return null;
	}
	
	@Transactional(readOnly=false)
	public BasePersonDto update(BasePersonDto personDto) {
		if (personDto != null) {
			BasePerson basePerson = personDtoMapper.to(personDto);
			BaseDepartment dept = null;
			String departmentGuid = personDto.getDepartmentGuid();
			if (StringUtils.isNotBlank(departmentGuid)) {
				dept = baseDepartmentRepository.findSelfById(departmentGuid);
			}
			if (dept != null && StringUtils.isNotBlank(dept.getId())) {
				basePerson.setDepartment(dept);
			}
			/*
			 * 设置所属角色
			 */
			List<BaseRole> roles = null;
			List<BaseRoleDto> roleDtos = personDto.getRoleDtos();
			if (roleDtos != null && roleDtos.size() != 0) {
				roles = new ArrayList<BaseRole>();
				for (BaseRoleDto baseRoleDto : roleDtos) {
					roles.add(new BaseRole(baseRoleDto.getId()));
				}
			}
			if (roles != null) {
				basePerson.setRoles(roles);
			}
			basePerson = personCache.saveAndFlush(basePerson);
			return personDtoMapper.from(basePerson);
		}
		return null;
	}

}
